package de.mmis.core.pojop.server;

import de.mmis.core.base.event.AbstractTypedEvent;
import de.mmis.core.base.event.Observable;

/**
 * interface representing a server on which an object can be published
 * 
 * @author Sebastian Bader
 * @author Christian Koch
 */
public interface Server extends Runnable, Observable<Server.ConnectionEvent> {

	/**
	 * event thrown if a client connects or disconnects. contains information
	 * about host and port of the client as well as whether disconnection was
	 * clean or dirty
	 * 
	 * @author Christian Koch
	 */
	public static class ConnectionEvent extends
			AbstractTypedEvent<ConnectionEvent.Type> {
		/**
		 * enum that decides whether the client connects or disconnects
		 * 
		 * @author Christian Koch
		 */
		public static enum Type {
			CONNECTION_STARTED, CONNECTION_ENDED
		}

		private boolean clean;
		private String host;
		private int port;

		/**
		 * used internally for struct S-Expression deserialization
		 */
		@Deprecated
		public ConnectionEvent() {
			super(null);
		}

		/**
		 * creates new {@link ConnectionEvent} with given parameters
		 * 
		 * @param type
		 *            type of event (connect/disconnect)
		 * @param host
		 *            host name or ip of the client
		 * @param port
		 *            port number used by the client
		 * @param clean
		 *            if set to <code>true</code>, the disconnect was done clean
		 */
		public ConnectionEvent(Type type, String host, int port, boolean clean) {
			super(type);
			this.host = host;
			this.port = port;
			this.clean = clean;
		}

		public boolean isClean() {
			return this.clean;
		}

		public void setClean(boolean clean) {
			this.clean = clean;
		}

		public String getHost() {
			return this.host;
		}

		public void setHost(String host) {
			this.host = host;
		}

		public int getPort() {
			return this.port;
		}

		public void setPort(int port) {
			this.port = port;
		}
	}

	/**
	 * @return the port number on which this server is listening to clients
	 */
	public int getPort();

	/**
	 * starts a new listening thread
	 * 
	 * @param name
	 *            The name of the thread
	 * 
	 * @return an already running Thread in which the server is listening to
	 *         clients
	 */
	public Thread start(String name);

	/**
	 * stops the server from waiting for client connections
	 */
	public void stopListening();
}
